import java.net.*;
import java.io.*;
import java.util.*;
/* This class handles a loose connection. A single socket is input through
 * the constructor, and passed to a new thread of this type. The idea is to
 * add a gameclass, somewhere, and then send strings up and down to that class.
 * If the server is re-used, this will be the maximum depth you can copy
 * without running into trouble.
 */
public class GameServerThread implements Runnable{
	Socket socket;
	BufferedReader is;
	PrintStream os;
	GameThreadStatus statusObject;

	ServerSocket ss;
	ClientInfo clientInfo;

	/* Constructor.
	 * <param id="socket">
	 * the socket with the connection with a client. maybe the port should
	 * be changed, because the connection is based on a single port number.
	 * </param>
	 * <param id="server">
	 * The parent server class. 
	 * </param>
	 */

	/* Constructor to create a new Thread for a connection with a client. It
	 * makes a new socket, on a random port, so multiple clients can be 
	 * accessed.
	 */
	public GameServerThread(Socket socket, GameThreadStatus statusObject){
		this.statusObject = statusObject;
		this.socket = socket;
		this.clientInfo = new ClientInfo();
		try{
			is = new BufferedReader(
					new InputStreamReader(
						socket.getInputStream()
					)
				);
			os = new PrintStream(socket.getOutputStream());
			socket.setSoTimeout(1000);
		} catch(IOException e){
		}
	}

	/* Method sets up communication with client, and makes it possible to 
	 * send strings up and down.
	 */
	public void run(){
		listenForInput();
	}


	public void listenForInput() {
		synchronized(statusObject){
			String decodedString;
			while(true){
				try{
					Thread.sleep(500);
					decodedString = is.readLine();
					while (decodedString != null) {
						System.out.println(decodedString);
						interpretInput(decodedString);
						System.out.println("Wating for next INput");
						decodedString = is.readLine();
					}
				} catch(Exception q){
					statusObject.living=false;
					break;
				}
				if(!socket.isConnected()){
					statusObject.living=false;
					break;
				}
			}
		}
	}

	public void sendString(String toSend){
		os.println(toSend + " \n");
	}

	public void interpretInput(String input){
		Scanner scanner = new Scanner(input);
		int firstInt = Integer.parseInt(scanner.next());
		System.out.println("input: " + input);
		if(clientInfo.userName == null && firstInt != 3 && firstInt !=0){
			// Print a login request to phone
			sendString("0");
			System.out.println("Sending Login Request");
		} else {
			String response = "";
			switch(firstInt){
				// Exit
				case(0):{
					try{
						socket.close();
						statusObject.living=false;
						break;
					} catch(java.io.IOException e){
						e.printStackTrace();
					}
				}
				// Send a chat message to world
				case(1):{
					System.out.println(input.substring(2));
					break;
				}
				// Send a chat message to id
				case(2):{
					break;
				}
				// login
				case(3):{
					clientInfo.userName = scanner.next();
					System.out.println("User logging in: " + clientInfo.userName);
					break;
				}
				default:{
						response = "no idea what happened";
				}
			}

		}
	}

	public void stop(){
		try{
		socket.close();
		} catch(java.io.IOException q){

		}
	}
}

class ClientInfo{
	public String userName;
}
